package com.ztgf.sys.service;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.ztgf.common.utils.StrUtils;
import com.ztgf.sys.common.config.YmlConfig;
import com.ztgf.sys.mapper.SysRoleMapper;
import com.ztgf.sys.mapper.SysRoleMenuRelationMapper;
import com.ztgf.sys.mapper.SysUserRoleRelationMapper;
import com.ztgf.sys.models.bo.*;
import com.ztgf.sys.models.constant.SysConstant;
import com.ztgf.sys.models.dto.SysRoleDTO;
import com.ztgf.sys.models.dto.SysUserDTO;
import com.ztgf.sys.models.enums.SYSCodeEnum;
import com.ztgf.sys.models.service.ISysRoleService;
import com.ztgf.sys.models.vo.SysMenuVO;
import com.ztgf.sys.models.vo.SysRoleVO;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * <p>
 * 角色表  服务实现类
 * </p>
 *
 * @author YUE
 * @since 2020-05-26
 */
@DubboService
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRoleDTO> implements ISysRoleService {

    @Autowired
    private SysRoleMenuRelationMapper sysRoleMenuRelationMapper;

    @Autowired
    private SysUserRoleRelationMapper sysUserRoleRelationMapper;

    @Autowired
    private SysUserServiceImpl sysUserService;

    @Autowired
    private SysMenuServiceImpl sysMenuService;

    @Autowired
    private SysRoleMenuRelationServiceImpl sysRoleMenuRelationService;

    @Autowired
    private SysUserRoleRelationServiceImpl sysUserRoleRelationService;

    @Resource
    private YmlConfig ymlConfig;

    @Autowired
    private SysConfigServiceImpl sysConfigService;

    /**
     * 根据店铺id获取拥有的角色信息
     * @param shopId
     * @return
     */
    @Override
    public List<SysRoleDTO> getRoleListByShopId(Long shopId){
        Wrapper<SysRoleDTO> wrapper = new EntityWrapper<>();
        wrapper.eq("shop_id", shopId);
        return selectList(wrapper);
    }

    /**
     * 根据平台类型来获取不同角色信息的子角色和菜单
     * @param sysRoleBO
     * @return
     */
    @Override
    public Page<SysRoleVO> selectPageRoleByWebType(SysRoleBO sysRoleBO){
        //查询所有的角色
        Page<SysRoleVO> sysRoleVOPage = getListByWebType(sysRoleBO);
        List<SysRoleVO> sysRoleVOList = sysRoleVOPage.getRecords();
        if(sysRoleVOList.size() == 0){
            return new Page<>();
        }
        //查询每个角色拥有的菜单
        for (SysRoleVO sysRoleVO : sysRoleVOList) {
            List<SysMenuVO> sysMenuVOS = sysRoleMenuRelationMapper.selectListMenuVOByRoleId(Arrays.asList(sysRoleVO.getId()));
            //List<SysMenuVO> treeSysMenuVO = sysMenuService.builTree(sysMenuVOS);
            sysRoleVO.setSysMenuVOList(sysMenuVOS);
        }
        //组装角色树
        if(sysRoleBO.getWebType() == SYSCodeEnum.WEB_TYPE_ADMIN.getCode()){
            sysRoleVOPage.setRecords(builTree(sysRoleVOList,SysConstant.ADMIN_ID)) ;
        }else{
            sysRoleVOPage.setRecords(builTree(sysRoleVOList,SysConstant.SHOP_MANAGER_ID));
        }
        return sysRoleVOPage;
    }

    /**
     * 根据平台类型来获取所有角色
     * @param sysRoleBO
     * @return
     */
    private Page<SysRoleVO> getListByWebType(SysRoleBO sysRoleBO){
        Page<SysRoleVO> page = new Page<>(sysRoleBO.getPageNo(), sysRoleBO.getPageSize());
        return page.setRecords(baseMapper.selectPageListByWebType(page,sysRoleBO));
    }

    /**
     * 根据父id查询所有的子角色
     * @param parentId
     * @return
     */
    @Override
    public List<SysRoleDTO> getRoleListByParentId(Long parentId){
        Wrapper<SysRoleDTO> wrapper = new EntityWrapper<>();
        wrapper.eq("parent_id", parentId);
        return selectList(wrapper);
    }

    /**
     * 添加角色
     * @param sysRoleSaveBO
     * @return
     */
    @Override
    public Long add(SysRoleSaveBO sysRoleSaveBO) {
        SysRoleDTO sysRoleDTO = new SysRoleDTO();
        BeanUtils.copyProperties(sysRoleSaveBO,sysRoleDTO);
        Long id = ymlConfig.getPkId();
        sysRoleDTO.setId(id);
        if(sysRoleDTO.getWebType() == SYSCodeEnum.WEB_TYPE_ADMIN.getCode()){
            //绑定与admin的关系
            //查询admin的用户信息
            SysUserDTO adminInfo = sysUserService.getAdminInfo();
            SysUserRoleRelationSaveBO sysUserRoleRelationSaveBO = new SysUserRoleRelationSaveBO();
            sysUserRoleRelationSaveBO.setRoleId(id);
            sysUserRoleRelationSaveBO.setUserId(adminInfo.getId());
            sysUserRoleRelationService.add(sysUserRoleRelationSaveBO);
            if(null == sysRoleDTO.getParentId()){//仅次于最大后台角色
                sysRoleDTO.setParentId(SysConstant.ADMIN_ID);
            }
            this.insert(sysRoleDTO);
            return id;
        }
        if(null == sysRoleDTO.getParentId()){//仅次于前端商家角色
            sysRoleDTO.setParentId(SysConstant.SHOP_MANAGER_ID);
        }
        Long shopId = sysRoleSaveBO.getShopId();
        String authorityIds = sysRoleSaveBO.getAuthorityIds();//菜单ids
        //需要绑定的菜单id集合
        String[] menuIdList = authorityIds.split(",");
        //绑定角色与菜单的关系
        for (String s : menuIdList) {
            if(StrUtils.isEmpty(s)){
                continue;
            }
            SysRoleMenuRelationSaveBO sysRoleMenuRelationSaveBO = new SysRoleMenuRelationSaveBO();
            sysRoleMenuRelationSaveBO.setShopId(shopId);
            sysRoleMenuRelationSaveBO.setMenuId(Long.parseLong(s));
            sysRoleMenuRelationSaveBO.setRoleId(id);
            sysRoleMenuRelationService.add(sysRoleMenuRelationSaveBO);
            //调用保存前端用户角色关联表
        }
        this.insert(sysRoleDTO);
        return id;
    }


    /**
     * 根据角色id删除角色
     * @param id 角色id
     * @return
     */
    @Transactional
    @Override
    public boolean deleteById(Long id) {
        //删除角色关系表以及角色以及子角色菜单信息
        deleteRoleRelationInfo(id);
        return true;
    }
    /**
     * 角色id
     * @param id 角色id
     */
    private void deleteRoleRelationInfo(Long id){
        List<SysRoleDTO> sysRoleDTOList = getRoleListByParentId(id);//当前角色的子角色集合
        for (SysRoleDTO sysRoleDTO : sysRoleDTOList) {
            Long roleId = sysRoleDTO.getId();
            deleteRoleRelationInfo(roleId);
        }
        //删除角色用户相关的信息
        sysUserRoleRelationService.deleteByRoleId(id);
        //删除当前角色下的菜单信息
        sysRoleMenuRelationService.deleteByRoleId(id);
        //删除当前角色
        baseMapper.deleteById(id);
    }

    /**
     * 所有角色 只取最高，低下的去掉
     * @param sysRoleIdList
     * @return
     */
    public boolean getAllRole(List<Long> sysRoleIdList,SysRoleDTO sysRoleDTO){
        Long parentRoleId = sysRoleDTO.getParentId();//父级Id
        //如果包含这个Id，则不要这个角色权限
        return !sysRoleIdList.contains(parentRoleId);
    }

    //建立树形结构
    public List<SysRoleVO> builTree(List<SysRoleVO> menuList, Long id){
        List<SysRoleVO> treeMenus =new ArrayList<>();
        for(SysRoleVO menuNode : getRootNode(menuList,id)) {
            menuNode=buildChilTree(menuNode,menuList);
            treeMenus.add(menuNode);
        }
        return treeMenus;
    }

    //递归，建立子树形结构
    private SysRoleVO buildChilTree(SysRoleVO pNode,List<SysRoleVO> menuList){
        List<SysRoleVO> chilMenus =new ArrayList<>();
        for(SysRoleVO menuNode : menuList) {
            if(menuNode.getParentId().equals(pNode.getId())) {
                chilMenus.add(buildChilTree(menuNode,menuList));
            }
        }
        pNode.setChildRoleList(chilMenus);
        return pNode;
    }

    //获取根节点
    private List<SysRoleVO> getRootNode(List<SysRoleVO> menuList,Long id) {
        List<SysRoleVO> rootMenuLists =new  ArrayList<>();
        for(SysRoleVO menuNode : menuList) {
            if(menuNode.getParentId().equals(id)) {
                rootMenuLists.add(menuNode);
            }
        }
        return rootMenuLists;
    }
}
